home *** CD-ROM | disk | FTP | other *** search
- getopt.c: An implementation of the UNIX getopt() C function.
-
- Author: Daniel J. Barrett, barrett@cs.umass.edu
- Status: Public domain
-
-
- WHAT IS GETOPT?
- ===============
-
- This is an implementation of the standard UNIX getopt() function.
- If you already know how to use it, you can ignore the rest of this file,
- because my implementation acts just like the UNIX getopt().
-
- Your program must #include "getopt.h" and link with getopt.o.
- Have fun!
-
- The rest of this file will teach you about getopt(). It is a
- function for C programmers. If you don't program in C, you can ignore
- this whole package, go home, and do something fun instead. :-)
-
-
- THE BASICS
- ==========
-
- getopt() is a function that makes it MUCH easier for a C program
- to process UNIX-like command-line options. A command-line option in UNIX
- is a single letter preceded by a dash, like this:
-
- -x
-
- A flexible program will let the user give options in any order,
- separately, grouped together, etc. However, all this can be a pain for the
- programmer. getopt() removes the pain.
-
-
- TERMINOLOGY
- ===========
-
- An OPTION appears on the command line and always begins with a dash.
-
- An ARGUMENT appears on the command line but is not an option.
- Arguments appear AFTER all of the options. If you have used UNIX before,
- you already know this... at least intuitively.
-
-
- A SIMPLE EXAMPLE OF USING GETOPT
- ================================
-
- Here is a simple example. Suppose you have a program called
- MyProgram which permits the options -a, -e, and -k. Also, it permits
- the option "-o" which MUST be followed by an output filename.
- Your main program will look something like this:
-
- main(int argc, char *argv[])
- {
- int c;
- char filename[BUFSIZ];
-
- while ((c = getopt(argc, argv, "aeko:")) != EOF)
- {
- switch (c)
- {
- case 'a':
- puts("I found the 'a' option.");
- DoSomething();
- break;
- case 'e':
- puts("I found the 'e' option.");
- DoSomethingElse();
- break
- case 'k':
- puts("I found the 'k' option.");
- DoAnotherThing();
- break;
- case 'o':
- puts("I found the 'o' option.");
- puts("It's followed by an argument.");
- strcpy(filename, optarg);
- break;
- case '?':
- default:
- puts("ERROR!");
- break;
- }
- }
- }
-
-
- On each iteration of the "while" loop, getopt() is executed, returning
- the NEXT command-line option's letter. When there are no more options,
- getopt() returns EOF.
-
- When a program uses getopt(), it allows the user to specify
- his/her options in any order, in any grouping. For example, the following
- invocations of the above program (suppose it is called "blammo") are
- all equivalent:
-
- 1> blammo -a -o myfile
- 1> blammo -a -omyfile
- 1> blammo -aek -o myfile
- 1> blammo -aek -omyfile
- 1> blammo -eo myfile -ka
- 1> blammo -eomyfile -ka
-
- Your program remains ignorant of the actual order and structure of the
- options -- getopt() handles all of this for you transparently.
-
-
- HOW A PROGRAMMER USES GETOPT
- ============================
-
- In order to use the getopt() function, follow these directions.
- Suppose you will be calling getopt() from inside main() in the file main.c.
- (This is just an example.)
-
- (1) At the top of main.c, include the mandatory header file:
-
- #include "getopt.h"
-
- This gives your program access to 4 important global variables:
-
- extern char *optarg;
- extern int optopt;
- extern int optind;
- extern int opterr;
-
- which are described later.
-
- (2) Create an option string: the third argument of getopt().
- There are two kinds of options:
-
- (a) Options that may appear alone.
- Examples: -a, -e, -k, in the above example.
-
- (b) Options that MUST be followed by a string.
- Example: Suppose the "-o" option must be followed by a
- filename. getopt() will enforce this fact.
-
- To create the option string, just make a single string with the
- option letters in any order. If an option must be followed by
- an string on the command line (as in the "-o" example), follow
- it IMMEDIATELY with a colon (':') in the option string.
-
- An option string that permits the -a, -e, and -k options, plus
- the "-o filename" option, would be:
-
- "aeko:"
-
- Order does not matter; any of the following would work too:
-
- "ao:ke"
- "o:eak"
- "eko:a"
-
- It is slightly more efficient to put the most commonly used options
- earlier in the string, but the speedup is almost unnoticeable.
-
- (3) If you do not want getopt() to print diagnostic messages, set the
- value of the global variable "opterr" to 0 in main()
-
- main(int argc, char *argv[])
- {
- ...
- opterr = 0;
- ...
- }
-
- before calling getopt().
-
- (4) Create your option-processing loop, as in the example at the top
- of this file.
-
-
- THE BEHAVIOR OF GETOPT
- ======================
-
- The function prototype for getopt() is:
-
- int getopt(int argc, char *argv[], char *optionString);
-
- where
-
- argc The first argument of main().
- argv The second argument of main().
- optionString The option string you created in step
- (2) of the previous section.
-
- getopt() returns one of three values:
-
- (1) If it reads a LEGAL option, it returns the option's
- character.
-
- If the legal option must be followed by a string, and THE
- STRING IS PRESENT, it returns the option's character.
-
- (2) If it reads an ILLEGAL option, it returns '?'.
-
- If it reads a legal option which must be followed by a
- string, but THE STRING IS MISSING, it returns '?' also.
-
- The option letter is now found in the global variable optopt.
-
- (3) If there are no more options, it returns EOF.
- If it encounters the special option "--", it returns EOF.
-
-
-
- THE GLOBAL VARIABLES
- ====================
-
- When you #include "getopt.h", you get access to 4 important
- global variables.
-
- extern char *optarg;
- extern int optopt;
- extern int optind;
- extern int opterr;
-
- These are documented carefully in getopt.h.
-
-
- HOW A USER USES GETOPT
- ======================
-
- The user may give the command-line options in any order:
-
- 1> blammo -a -e -k
- 1> blammo -k -a -e
- 1> blammo -e -k -a
- etc...
-
- or any grouping
-
- 1> blammo -aek
- 1> blammo -ek -a
- 1> blammo -k -ea
-
- If an option (like "-o") MUST be followed by a string (like "myfile"), the
- user may put the string immediately after the option:
-
- 1> blammo -omyfile
-
- or separated by whitespace:
-
- 1> blammo -o myfile
- 1> blammo -o myfile
-
- All options must precede all arguments. The following examples
- are WRONG:
-
- 1> blammo anything -a -e -k /* WRONG!!! */
- 1> blammo -o myfile anything -e /* WRONG!!! */
-
- because the argument "anything" appears before options. In the first
- example, getopt() will see no options and return EOF, with optind == 1.
- In the second example, getopt() will find the "-o" option and its
- string "myfile", and then return EOF with optind==3. It will not see the
- "-e" option.
-
- The special option "--" means "there are no more options." It
- is useful when an argument must begin with a dash, but you don't want
- getopt() to process it. When getopt() reads "--", it returns EOF
- immediately, with optind containing the index of the first argument
- after the "--".
-
- 1> blammo -e -- -x -y
-
- In this example, getopt() finds the "-e" option (and returns 'e'),
- then sees "--", and returns EOF. optind is now 3, with argv[optind] == "-x".
-
-
- FACTS ABOUT GETOPT
- ==================
-
- (1) When getopt() encounters a legal option, it returns the option
- character. For example, on encountering the "-e" option, getopt()
- returns 'e'.
-
- (2) When getopt() encounters an illegal option (not given in the
- option string, or missing its following string), it returns
- the character '?'. The true option character is found in the
- global variable optopt.
-
- (3) When there are no more options, getopt() returns EOF.
-
- (4) getopt() has no other return values but the three given above:
- a character from the option string, a '?' character, or EOF.
-
- (5) The special option "--" (two dashes) means "end of options."
- When getopt() encounters "--", getopt() returns EOF.
-
- This is useful if some of your arguments must begin with dashes.
- For example, in our above example, suppose we want to follow our
- options with the argument "-MyArg". If we type:
-
- 1> blammo -MyArg
-
- then getopt() will interpret the 'M' (and possibly the remaining
- characters) as options, and print error messages. But if we type:
-
- 1> blammo -- -MyArg
-
- then getopt() quits processing, and argv[optind] == "-MyArg" as
- we wanted.
-
- (6) After getopt() returns EOF, the next argument your program
- should process is argv[optind].
-
- A typical loop for processing the rest of the argument might be:
-
- for (i=optind; i<argc; i++)
- Process(argv[i]);
-
- If optind > argc-1, then there are no more arguments to process.
-
- (7) optarg changes its value on every call of getopt().
- Thus, the following is a BUG:
-
- char *filename;
- filename = optarg;
- getopt(argc, argv, "aejo:");
- printf("The filename is %s\n", filename);
-
- After the call to getopt(), filename is not guaranteed to point at
- anything meaningful. If you want to save the value of optarg,
- copy it into a private string buffer; for example,
-
- char filename[BIG_ENOUGH_SIZE];
- strcpy(filename, optarg);
-
- (8) getopt() iterates through the options ONLY ONCE.
-
- After getopt() returns EOF, it is useless to you. You should NOT
- call it again before the program exits.
-
- (9) NEVER change the values of optind, optopt, and optarg.
-
- These variables should be treated as READ-ONLY.
- However, it is OK to set the value of opterr.
-
- (10) While getopt() is actively being used, DO NOT modify argc and
- argv.
-
- (11) The names getopt, optind, optarg, optopt, and opterr are historical.
- They are the same in (I hope) all implementations of getopt().
- You should not change them if you want your code to be portable.
-
- (12) Options are CASE SENSITIVE.
-
- The options "-a" and "-A" are different.
-
- (13) The option "-:" (dash colon) is illegal. Your program should
- never require this option.
-
-
- AN EXAMPLE OF USING GETOPT
- ==========================
-
- A complete getopt() example is found in example.c.
-
- Another example is found in getopt.c. The main() function is
- commented out using the preprocessor macro TESTME. Use your compiler to
- #define TESTME, and compile/link getopt.c to create an executable test
- program.
-
-
- A NOTE FOR MANX AZTEC C USERS
- =============================
-
- The enclosed Makefile will create link libraries for you.
-
- If you link with one of these libraries (say, getopt.lib),
- you MUST specify "-lgetopt" before "-lc".
-
- 1> ln myfile.o -lc -lgetopt /* WRONG!!! */
- 1> ln myfile.o -lgetopt -lc /* CORRECT. */
-